package com.huanong.it.xwuser.authority.common.filter;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huanong.it.xwuser.authority.common.entity.MyConst;
import com.huanong.it.xwuser.authority.common.exception.CaptchaException;
import com.huanong.it.xwuser.authority.common.utils.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


public class LoginFilter extends UsernamePasswordAuthenticationFilter {

    @Autowired
    private RedisUtil redisUtil;
    @Value("${spring.security.enable-captcha}")
    private Boolean enableCaptcha;
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        // 需要是 POST 请求
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }

        // 判断请求格式是否是 JSON
        if (request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE) || request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE)) {
            //读取json格式的数据
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jn= null;
            try {

                jn = objectMapper.readTree(request.getInputStream());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            JsonNode usernameJN=jn.get(getUsernameParameter());
            JsonNode passwordJN=jn.get(getPasswordParameter());
            if(usernameJN!=null&&usernameJN.asText().isEmpty()||passwordJN!=null&&passwordJN.asText().isEmpty()){
                throw new AuthenticationServiceException("用户名或密码不能为空");
            }

            String username = usernameJN.asText();
            String password = passwordJN.asText();
            if(enableCaptcha) {
                validate(jn);
            }
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
                    username, password);
            setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);
        }else {
            return super.attemptAuthentication(request, response);
        }
    }
    private void validate(JsonNode jn) throws CaptchaException {
            JsonNode usernameJN = jn.get("code");
            JsonNode passwordJN = jn.get("token");
            if(usernameJN==null||passwordJN==null){
                throw new AuthenticationServiceException("验证码或token不能为空");
            }
            if (usernameJN != null && usernameJN.asText().isEmpty() || passwordJN != null && passwordJN.asText().isEmpty()) {
                throw new AuthenticationServiceException("验证码或token不能为空");
            }

            String code = usernameJN.asText();
            String token = passwordJN.asText();

            if (StringUtils.isBlank(code) || StringUtils.isBlank(token)) {
                throw new CaptchaException("验证码不能为空");
            }
            if(!code.equals(redisUtil.hget(MyConst.CAPTCHA_KEY, token))) {
                throw new CaptchaException("验证码不正确");
            }
            // 一次性使用
            redisUtil.hdel(MyConst.CAPTCHA_KEY, token);

    }
}



